/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.siteEncheres.client.seance;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.form.DateField;
import com.gwtext.client.widgets.form.Label;
import com.gwtext.client.widgets.form.TextArea;
import com.gwtext.client.widgets.form.TimeField;
import com.gwtext.client.widgets.layout.HorizontalLayout;
import com.gwtext.client.widgets.layout.VerticalLayout;
import domain.Categorie;
import domain.Image;
import domain.Produit;
import domain.Observer.Seance;
import domain.Utilisateur;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.siteEncheres.client.DoubleBox;

/**
 *
 * @author Francois
 */
public class IhmCreerSeance extends Panel {
    
    private TextBox txtTitre = new TextBox();
    private ListBox listeCat = new ListBox();
    //listbox (invisible sur la page) qui sert à faire la correspondance
    //entre le nom de la categorie et son id.
    private ListBox listeIdCat = new ListBox();
    private TextArea txtDesc = new TextArea();
    private DateField dateOuverture = new DateField("Date d'ouverture", "truc", 140);
    private TimeField heureOuverture = new TimeField();
    private DateField dateFermeture = new DateField("Date de fermeture", "truc", 140);
    private TimeField heureFermeture = new TimeField();
    private DoubleBox txtPrixDepart = new DoubleBox();
    private DoubleBox txtPrixReserve = new DoubleBox();
    private Button btnCreer = new Button("Créer");
    private Utilisateur vendeur;
    private Date dateActuelle;
    private FormulaireUpload form;
    
    final AsyncCallback<Utilisateur> callbackUtilisateurEnCours = new AsyncCallback<Utilisateur>() {
        
        @Override
        public void onSuccess(Utilisateur u) {
            vendeur = u;
        }
        
        @Override
        public void onFailure(Throwable caught) {
            String exception = formaterException(caught.getMessage());
            MessageBox.alert(exception);
        }
    };
    
    final AsyncCallback<Date> callbackDateActuelle = new AsyncCallback<Date>() {
        
        @Override
        public void onSuccess(java.util.Date d) {
            dateActuelle = d;
        }
        
        @Override
        public void onFailure(Throwable caught) {
            String exception = formaterException(caught.getMessage());
            MessageBox.alert(exception);
        }
    };
    
    final AsyncCallback<List<Categorie>> callbackCategories = new AsyncCallback<List<Categorie>>() {
        
        @Override
        public void onSuccess(List<Categorie> liste) {
            //On remplis la liste des categories pour l utilisateur
            //mais aussi une seconde listBox qui sera invisble, et qui sert 
            //seulement à faire la correspondance entre le nom de la 
            //categorie et son id (qui est demande lors de l'ajout de la seance)
            for (Iterator<Categorie> it = liste.iterator(); it.hasNext();) {
                Categorie categorie = it.next();
                listeCat.addItem(categorie.getNom());
                Integer idCat = categorie.getId_categorie();
                listeIdCat.addItem(idCat.toString());
            }
        }
        
        @Override
        public void onFailure(Throwable caught) {
            String exception = formaterException(caught.getMessage());
            MessageBox.alert(exception);
        }
    };
    
    final AsyncCallback callbackCreationSeance = new AsyncCallback() {
        
        @Override
        public void onSuccess(Object result) {
            txtTitre.setText("");
            listeCat.setItemSelected(0, true);
            listeIdCat.setItemSelected(0, true);
            txtDesc.setValue("");
            txtPrixDepart.setText("");
            txtPrixReserve.setText("");
            dateOuverture.setValue("");
            heureOuverture.setValue("");
            dateFermeture.setValue("");
            heureFermeture.setValue("");
        }
        
        @Override
        public void onFailure(Throwable caught) {
            String exception = formaterException(caught.getMessage());
            MessageBox.alert(exception);
        }
    };
    
    public IhmCreerSeance() {
        setFrame(true);
        setBorder(false);
        setTitle("Création d'une séance");
        setWidth(550);
        setLayout(new VerticalLayout(10));

        ///////////// Panel Titre ///////////////////
        Panel pTitre = new Panel();
        pTitre.setLayout(new HorizontalLayout(10));
        pTitre.add(new Label("Titre de l'objet"));
        txtTitre.setMaxLength(50);
        pTitre.add(txtTitre);
        add(pTitre);
        /////////////////////////////////////////////

        ///////////// Panel Catégorie ///////////////////
        Panel pCat = new Panel();
        pCat.setLayout(new HorizontalLayout(10));
        pCat.add(new Label("Catégorie de l'objet"));
        listeCat.addItem("--Catégorie--");
        
        Panel pIdCat = new Panel();
        listeIdCat.addItem("--Catégorie--");
        pIdCat.add(listeIdCat);
        pIdCat.setVisible(false);
        pCat.add(listeCat);
        pCat.add(pIdCat);
        add(pCat);
        /////////////////////////////////////////////

        ///////////// Panel Description ///////////////////
        Panel pDesc = new Panel();
        pDesc.setLayout(new VerticalLayout());
        pDesc.add(new Label("Description de l'objet"));
        txtDesc.setMaxLength(50);
        txtDesc.setSize(250, 50);
        pDesc.add(txtDesc);
        add(pDesc);
        /////////////////////////////////////////////

        ///////////// Panel date d'ouverture ///////////////////
        Panel dateTimeOuverture = new Panel();
        dateTimeOuverture.setLayout(new HorizontalLayout(10));
        dateTimeOuverture.add(new Label("Date d'ouverture"));
        dateTimeOuverture.add(dateOuverture);
        heureOuverture.setHideLabel(true);
        heureOuverture.setWidth(80);
        dateTimeOuverture.add(heureOuverture);
        add(dateTimeOuverture);
        /////////////////////////////////////////////

        ///////////// Panel date de fermeture ///////////////////
        Panel dateTimeFermeture = new Panel();
        dateTimeFermeture.setLayout(new HorizontalLayout(10));
        dateTimeFermeture.add(new Label("Date de fermeture"));
        dateTimeFermeture.add(dateFermeture);
        heureFermeture.setHideLabel(true);
        heureFermeture.setWidth(80);
        dateTimeFermeture.add(heureFermeture);
        add(dateTimeFermeture);
        /////////////////////////////////////////////

        ///////////// Panel prix de départ ///////////////////
        Panel pPrixDepart = new Panel();
        pPrixDepart.setLayout(new HorizontalLayout(10));
        pPrixDepart.add(new Label("Prix de départ"));
        txtPrixDepart.setMaxLength(6);
        pPrixDepart.add(txtPrixDepart);
        add(pPrixDepart);
        /////////////////////////////////////////////

        ///////////// Panel prix de réserve ///////////////////
        Panel pPrixReserve = new Panel();
        pPrixReserve.setLayout(new HorizontalLayout(10));
        pPrixReserve.add(new Label("Prix de réserve"));
        txtPrixReserve.setMaxLength(6);
        pPrixReserve.add(txtPrixReserve);
        add(pPrixReserve);
        /////////////////////////////////////////////
        Panel panelUpload = new Panel();
        form = new FormulaireUpload(new FileUpload());
        panelUpload.add(form);
        add(panelUpload);

        add(btnCreer);
        //On recupere l'utilisateur en cours pour savoir
        //qui est le vendeur.
        getService().getUtilisateurEnCours(callbackUtilisateurEnCours);
        //On recupere la date actuelle pour pourvoir verifier les 
        //dates saisies par l'utilisateur.
        getService().getDateActuelle(callbackDateActuelle);
        //On recupere les categories pour les afficher dans les listbox.
        getService().getAllCategorie(callbackCategories);
        
        btnCreer.addClickHandler(new ClickHandler() {
            
            @Override
            public void onClick(ClickEvent w) {
                
                Timestamp dateOuv = formaterDate(dateOuverture.getValue(), heureOuverture.getValue());
                Timestamp dateFerm = formaterDate(dateFermeture.getValue(), heureFermeture.getValue());
                
                //On verifie que la date d ouverture n'est pas passee.
                if (VerifierDate(dateOuv.getTime(), dateActuelle.getTime()) == 1) {
                    MessageBox.alert("ERREUR ! la date de début est déjà passée.");
                //On verifie que la date de fermeture n est pas passee.
                } else if (VerifierDate(dateFerm.getTime(), dateActuelle.getTime()) == 1) {
                    MessageBox.alert("ERREUR ! la date de fin est déjà passée.");
                //On verifie que l ecart entre les 2 dates est positif.
                } else if (VerifierDate(dateOuv.getTime(), dateFerm.getTime()) != 1) {
                    MessageBox.alert("ERREUR ! la date de début est supérieur ou égale à la date de fin.");
                //On verifie que les champs obligatoires soit remplis.
                } else if (!verifChampsVides()) {
                    MessageBox.alert("ERREUR ! Tous les champs sont obligatoires à"
                            + " l'exception de la description et du prix de réserve.");
                //Si tous les tests precedent sont bon, on ajoute la seance.
                } else {
                    Seance seance = new Seance();
                    Produit produit = new Produit();
                    Categorie categorie = new Categorie();
                    
                    produit.setTitre(txtTitre.getText());
                    produit.setDescription(txtDesc.getText());
                    categorie.setId_categorie(Integer.parseInt(listeIdCat.getValue(listeCat.getSelectedIndex())));
                    produit.setCategorie(categorie);
                    List<Image> listeImage = new ArrayList<Image>();
                    Image im = new Image();
                    im.setCheminFichier("chemin du fichier");
                    listeImage.add(im);
                    produit.setImages(listeImage);
                    seance.setProduit(produit);
                    seance.setId_vendeur(vendeur.getIdUtilisateur());
                    seance.setDate_ouverture(dateOuv);
                    seance.setDate_fermeture(dateFerm);
                    seance.setPrix_depart(Double.parseDouble(txtPrixDepart.getText()));
                    seance.setReserve(Double.parseDouble(txtPrixReserve.getText()));
                    form.submit();
                    getService().creerSeance(seance, vendeur.getIdUtilisateur(), callbackCreationSeance);
                }
            }
        });
    }
    
    public static GwtSeanceAsync getService() {
        return GWT.create(GwtSeance.class);
    }

    /*
     * @return return true si les champs obligatoires du formulaire
     * sont remplis.
     */
    public boolean verifChampsVides() {
        if (txtTitre.getText().compareTo("") == 0) {
            return false;
        }
        if (txtPrixDepart.getText().compareTo("") == 0) {
            return false;
        }
        if (listeCat.getSelectedIndex() == 0) {
            return false;
        }
        return true;
    }

    /**
     * 
     * @param dateDebut
     * @param dateFin
     * @return 0 si les dates sont egales, -1 si la date de fin est inferieur
     * a la date de début, 1 si la date de fin est superieur
     * a la date de début, -2 sinon (erreur)
     */
    public int VerifierDate(long dateDebut, long dateFin) {
        long diff = dateFin - dateDebut;
        if (diff == 0) {
            return 0;
        }
        if (diff < 0) {
            return -1;
        }
        if (diff > 0) {
            return 1;
        }
        return -2;
    }

    /**
     * 
     * @param date
     * @param horaire
     * @return Retourne la date au format TimeStamp
     */
    public Timestamp formaterDate(java.util.Date date, String horaire) {
        //1er split de la date
        //On peut recuperer une date au format  12 Jan 2012 
        String[] splitDate = date.toString().split(" ");
        String jour = splitDate[2];
        String mois = null;
        String annee = splitDate[5];
        String heure;
        String minute;
        //On remplace le mois ecrit en letrre par des chiffres
        //pour pourvoir etre conforme au TimeStamp
        if (splitDate[1].compareTo("Jan") == 0) mois = "01";
        if (splitDate[1].compareTo("Feb") == 0) mois = "02";
        if (splitDate[1].compareTo("Mar") == 0) mois = "03";
        if (splitDate[1].compareTo("Apr") == 0) mois = "04";
        if (splitDate[1].compareTo("May") == 0) mois = "05";
        if (splitDate[1].compareTo("Jun") == 0) mois = "06";
        if (splitDate[1].compareTo("Jul") == 0) mois = "07";
        if (splitDate[1].compareTo("Aug") == 0) mois = "08";
        if (splitDate[1].compareTo("Sep") == 0) mois = "09";
        if (splitDate[1].compareTo("Oct") == 0) mois = "10";
        if (splitDate[1].compareTo("Nov") == 0) mois = "11";
        if (splitDate[1].compareTo("Dec") == 0) mois = "12";

        //On split l heure une 1ere fois pr recuperer d'un cote l heure
        //et de l'autre le AM ou PM de l heure
        String[] splitHoraire = horaire.split(" ");
        //2nd split ensuite pour separer les heures des minutes
        String[] splitHeureMinute = splitHoraire[0].split(":");

        //si le resultat du split donne AM, on ne fais rien
        if (splitHoraire[1].compareTo("AM") == 0) {
            heure = splitHeureMinute[0];
        } //Mais le resultat du split donne PM, on rajoute 12 a l heure
        //pour avoir un resultat sur 24 heures.
        else {
            Integer heureApresMidi = Integer.parseInt(splitHeureMinute[0]) + 12;
            heure = heureApresMidi.toString();
        }
        minute = splitHeureMinute[1];
        return Timestamp.valueOf(annee + "-" + mois + "-" + jour + " " + heure + ":" + minute + ":00");
    }
    
    /**
     * Méthode servant a separer le "java.lang.Exception:" du
     * message de l'exception qu on ne veut pas a l affichage.
     * 
     * @param exception Message contenu dans l exception.
     * @return ce qu il y a apres le "java.lang.Exception"
     * si cette chaine est presente, le message en entier sinon.
     */
    public String formaterException(String exception){
        String[] split = exception.split(":");
        if(split[0].compareTo("java.lang.Exception") == 0){
            return split[1];
        }
        else return exception;
    }
}
